package gateway.rule.outbound;

import gateway.api.annotation.GatewayType;
import gateway.api.annotation.Named;
import gateway.api.aware.HttpClientAware;
import gateway.api.engine.Outbound;
import gateway.api.message.Message;
import gateway.rule.path.UrlUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Map;

/**
 * @author Jin Zheng
 * @since 1.0 2020-09-11
 */
@Named(value = "httpOutbound", type = GatewayType.HTTP, async = false)
public class HttpOutbound implements Outbound, HttpClientAware
{
	private static Logger logger = LoggerFactory.getLogger(HttpOutbound.class);
	public static final String HOST = "host";
	public static final String PATH = "path";
	public static final String METHOD = "method";

	private HttpClient httpClient;
	private Map<String, String> args;

	public HttpOutbound()
	{
	}

	@Override
	public void send(Message message)
	{
		String host = args.get(HOST);
		String path = args.get(PATH);
		String method = args.get(METHOD);
		byte[] buf = message.byteArray();

		String url = UrlUtil.template(path, message.context().args());
		logger.info("path: {}", url);
		HttpRequest request = HttpRequest.newBuilder()
				.uri(URI.create("http://" + host + url))
				.method(method.toUpperCase(), HttpRequest.BodyPublishers.ofByteArray(buf))
				.build();
		httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString())
				.thenApply(HttpResponse::body)
				.thenAccept(c -> logger.info("Response: {}", c));
	}

	@Override
	public void setArgs(Map<String, String> args)
	{
		this.args = args;
	}

	@Override
	public void setHttpClient(HttpClient httpClient)
	{
		this.httpClient = httpClient;
	}
}
